1/* $NetBSD: postfix.c,v 1.2 2017/02/14 01:16:46 christos Exp $ */
2
3/*++
4/* NAME
5/* postfix 1
6/* SUMMARY
7/* Postfix control program
8/* SYNOPSIS
9/* .fi
10/* \fBpostfix\fR [\fB-Dv\fR] [\fB-c \fIconfig_dir\fR] \fIcommand\fR
11/* DESCRIPTION
12/* This command is reserved for the superuser. To submit mail,
13/* use the Postfix \fBsendmail\fR(1) command.
14/*
15/* The \fBpostfix\fR(1) command controls the operation of the Postfix
16/* mail system: start or stop the \fBmaster\fR(8) daemon, do a health
17/* check, and other maintenance.
18/*
19/* By default, the \fBpostfix\fR(1) command sets up a standardized
20/* environment and runs the \fBpostfix-script\fR shell script
21/* to do the actual work.
22/*
23/* However, when support for multiple Postfix instances is
24/* configured, \fBpostfix\fR(1) executes the command specified
25/* with the \fBmulti_instance_wrapper\fR configuration parameter.
26/* This command will execute the \fIcommand\fR for each
27/* applicable Postfix instance.
28/*
29/* The following commands are implemented:
30/* .IP \fBcheck\fR
31/* Warn about bad directory/file ownership or permissions,
32/* and create missing directories.
33/* .IP \fBstart\fR
34/* Start the Postfix mail system. This also runs the configuration
35/* check described above.
36/* .IP \fBstop\fR
37/* Stop the Postfix mail system in an orderly fashion. If
38/* possible, running processes are allowed to terminate at
39/* their earliest convenience.
40/* .sp
41/* Note: in order to refresh the Postfix mail system after a
42/* configuration change, do not use the \fBstart\fR and \fBstop\fR
43/* commands in succession. Use the \fBreload\fR command instead.
44/* .IP \fBabort\fR
45/* Stop the Postfix mail system abruptly. Running processes are
46/* signaled to stop immediately.
47/* .IP \fBflush\fR
48/* Force delivery: attempt to deliver every message in the deferred
49/* mail queue. Normally, attempts to deliver delayed mail happen at
50/* regular intervals, the interval doubling after each failed attempt.
51/* .sp
52/* Warning: flushing undeliverable mail frequently will result in
53/* poor delivery performance of all other mail.
54/* .IP \fBreload\fR
55/* Re-read configuration files. Running processes terminate at their
56/* earliest convenience.
57/* .IP \fBstatus\fR
58/* Indicate if the Postfix mail system is currently running.
59/* .IP "\fBset-permissions\fR [\fIname\fR=\fIvalue ...\fR]"
60/* Set the ownership and permissions of Postfix related files and
61/* directories, as specified in the \fBpostfix-files\fR file.
62/* .sp
63/* Specify \fIname\fR=\fIvalue\fR to override and update specific
64/* main.cf configuration parameters. Use this, for example, to
65/* change the \fBmail_owner\fR or \fBsetgid_group\fR setting for an
66/* already installed Postfix system.
67/* .sp
68/* This feature is available in Postfix 2.1 and later. With
69/* Postfix 2.0 and earlier, use "\fB$config_directory/post-install
70/* set-permissions\fR".
71/* .IP "\fBtls\fR \fIsubcommand\fR"
72/* Enable opportunistic TLS in the Postfix SMTP client or
73/* server, and manage Postfix SMTP server TLS private keys and
74/* certificates. See postfix-tls(1) for documentation.
75/* .sp
76/* This feature is available in Postfix 3.1 and later.
77/* .IP "\fBupgrade-configuration\fR [\fIname\fR=\fIvalue ...\fR]"
78/* Update the \fBmain.cf\fR and \fBmaster.cf\fR files with information
79/* that Postfix needs in order to run: add or update services, and add
80/* or update configuration parameter settings.
81/* .sp
82/* Specify \fIname\fR=\fIvalue\fR to override and update specific
83/* main.cf configuration parameters.
84/* .sp
85/* This feature is available in Postfix 2.1 and later. With
86/* Postfix 2.0 and earlier, use "\fB$config_directory/post-install
87/* upgrade-configuration\fR".
88/* .PP
89/* The following options are implemented:
90/* .IP "\fB-c \fIconfig_dir\fR"
91/* Read the \fBmain.cf\fR and \fBmaster.cf\fR configuration files in
92/* the named directory instead of the default configuration directory.
93/* Use this to distinguish between multiple Postfix instances on the
94/* same host.
95/*
96/* With Postfix 2.6 and later, this option forces the postfix(1)
97/* command to operate on the specified Postfix instance only.
98/* This behavior is inherited by postfix(1) commands that run
99/* as a descendant of the current process.
100/* .IP "\fB-D\fR (with \fBpostfix start\fR only)"
101/* Run each Postfix daemon under control of a debugger as specified
102/* via the \fBdebugger_command\fR configuration parameter.
103/* .IP \fB-v\fR
104/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
105/* options make the software increasingly verbose.
106/* ENVIRONMENT
107/* .ad
108/* .fi
109/* The \fBpostfix\fR(1) command exports the following environment
110/* variables before executing the \fBpostfix-script\fR file:
111/* .IP \fBMAIL_CONFIG\fR
112/* This is set when the -c command-line option is present.
113/*
114/* With Postfix 2.6 and later, this environment variable forces
115/* the postfix(1) command to operate on the specified Postfix
116/* instance only. This behavior is inherited by postfix(1)
117/* commands that run as a descendant of the current process.
118/* .IP \fBMAIL_VERBOSE\fR
119/* This is set when the -v command-line option is present.
120/* .IP \fBMAIL_DEBUG\fR
121/* This is set when the -D command-line option is present.
122/* CONFIGURATION PARAMETERS
123/* .ad
124/* .fi
125/* The following \fBmain.cf\fR configuration parameters are
126/* exported as environment variables with the same names:
127/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
128/* The default location of the Postfix main.cf and master.cf
129/* configuration files.
130/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
131/* The location of all postfix administrative commands.
132/* .IP "\fBdaemon_directory (see 'postconf -d' output)\fR"
133/* The directory with Postfix support programs and daemon programs.
134/* .IP "\fBhtml_directory (see 'postconf -d' output)\fR"
135/* The location of Postfix HTML files that describe how to build,
136/* configure or operate a specific Postfix subsystem or feature.
137/* .IP "\fBmail_owner (postfix)\fR"
138/* The UNIX system account that owns the Postfix queue and most Postfix
139/* daemon processes.
140/* .IP "\fBmailq_path (see 'postconf -d' output)\fR"
141/* Sendmail compatibility feature that specifies where the Postfix
142/* \fBmailq\fR(1) command is installed.
143/* .IP "\fBmanpage_directory (see 'postconf -d' output)\fR"
144/* Where the Postfix manual pages are installed.
145/* .IP "\fBnewaliases_path (see 'postconf -d' output)\fR"
146/* Sendmail compatibility feature that specifies the location of the
147/* \fBnewaliases\fR(1) command.
148/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
149/* The location of the Postfix top-level queue directory.
150/* .IP "\fBreadme_directory (see 'postconf -d' output)\fR"
151/* The location of Postfix README files that describe how to build,
152/* configure or operate a specific Postfix subsystem or feature.
153/* .IP "\fBsendmail_path (see 'postconf -d' output)\fR"
154/* A Sendmail compatibility feature that specifies the location of
155/* the Postfix \fBsendmail\fR(1) command.
156/* .IP "\fBsetgid_group (postdrop)\fR"
157/* The group ownership of set-gid Postfix commands and of group-writable
158/* Postfix directories.
159/* .PP
160/* Available in Postfix version 2.5 and later:
161/* .IP "\fBdata_directory (see 'postconf -d' output)\fR"
162/* The directory with Postfix-writable data files (for example:
163/* caches, pseudo-random numbers).
164/* .PP
165/* Available in Postfix version 3.0 and later:
166/* .IP "\fBmeta_directory (see 'postconf -d' output)\fR"
167/* The location of non-executable files that are shared among
168/* multiple Postfix instances, such as postfix-files, dynamicmaps.cf,
169/* and the multi-instance template files main.cf.proto and master.cf.proto.
170/* .IP "\fBshlib_directory (see 'postconf -d' output)\fR"
171/* The location of Postfix dynamically-linked libraries
172/* (libpostfix-*.so), and the default location of Postfix database
173/* plugins (postfix-*.so) that have a relative pathname in the
174/* dynamicmaps.cf file.
175/* .PP
176/* Available in Postfix version 3.1 and later:
177/* .IP "\fBopenssl_path (openssl)\fR"
178/* The location of the OpenSSL command line program \fBopenssl\fR(1).
179/* .PP
180/* Other configuration parameters:
181/* .IP "\fBimport_environment (see 'postconf -d' output)\fR"
182/* The list of environment parameters that a Postfix process will
183/* import from a non-Postfix parent process.
184/* .IP "\fBsyslog_facility (mail)\fR"
185/* The syslog facility of Postfix logging.
186/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
187/* The mail system name that is prepended to the process name in syslog
188/* records, so that "smtpd" becomes, for example, "postfix/smtpd".
189/* .PP
190/* Available in Postfix version 2.6 and later:
191/* .IP "\fBmulti_instance_directories (empty)\fR"
192/* An optional list of non-default Postfix configuration directories;
193/* these directories belong to additional Postfix instances that share
194/* the Postfix executable files and documentation with the default
195/* Postfix instance, and that are started, stopped, etc., together
196/* with the default Postfix instance.
197/* .IP "\fBmulti_instance_wrapper (empty)\fR"
198/* The pathname of a multi-instance manager command that the
199/* \fBpostfix\fR(1) command invokes when the multi_instance_directories
200/* parameter value is non-empty.
201/* .IP "\fBmulti_instance_group (empty)\fR"
202/* The optional instance group name of this Postfix instance.
203/* .IP "\fBmulti_instance_name (empty)\fR"
204/* The optional instance name of this Postfix instance.
205/* .IP "\fBmulti_instance_enable (no)\fR"
206/* Allow this Postfix instance to be started, stopped, etc., by a
207/* multi-instance manager.
208/* FILES
209/* .ad
210/* .fi
211/* Prior to Postfix version 2.6, all of the following files
212/* were in \fB$config_directory\fR. Some files are now in
213/* \fB$daemon_directory\fR so that they can be shared among
214/* multiple instances that run the same Postfix version.
215/*
216/* Use the command "\fBpostconf config_directory\fR" or
217/* "\fBpostconf daemon_directory\fR" to expand the names
218/* into their actual values.
219/* .na
220/* .nf
221/*
222/* $config_directory/main.cf, Postfix configuration parameters
223/* $config_directory/master.cf, Postfix daemon processes
224/* $daemon_directory/postfix-files, file/directory permissions
225/* $daemon_directory/postfix-script, administrative commands
226/* $daemon_directory/post-install, post-installation configuration
227/* $daemon_directory/dynamicmaps.cf, plug-in database clients
228/* SEE ALSO
229/* Commands:
230/* postalias(1), create/update/query alias database
231/* postcat(1), examine Postfix queue file
232/* postconf(1), Postfix configuration utility
233/* postfix(1), Postfix control program
234/* postfix-tls(1), Postfix TLS management
235/* postkick(1), trigger Postfix daemon
236/* postlock(1), Postfix-compatible locking
237/* postlog(1), Postfix-compatible logging
238/* postmap(1), Postfix lookup table manager
239/* postmulti(1), Postfix multi-instance manager
240/* postqueue(1), Postfix mail queue control
241/* postsuper(1), Postfix housekeeping
242/* mailq(1), Sendmail compatibility interface
243/* newaliases(1), Sendmail compatibility interface
244/* sendmail(1), Sendmail compatibility interface
245/*
246/* Postfix configuration:
247/* bounce(5), Postfix bounce message templates
248/* master(5), Postfix master.cf file syntax
249/* postconf(5), Postfix main.cf file syntax
250/* postfix-wrapper(5), Postfix multi-instance API
251/*
252/* Table-driven mechanisms:
253/* access(5), Postfix SMTP access control table
254/* aliases(5), Postfix alias database
255/* canonical(5), Postfix input address rewriting
256/* generic(5), Postfix output address rewriting
257/* header_checks(5), body_checks(5), Postfix content inspection
258/* relocated(5), Users that have moved
259/* transport(5), Postfix routing table
260/* virtual(5), Postfix virtual aliasing
261/*
262/* Table lookup mechanisms:
263/* cidr_table(5), Associate CIDR pattern with value
264/* ldap_table(5), Postfix LDAP client
265/* lmdb_table(5), Postfix LMDB database driver
266/* memcache_table(5), Postfix memcache client
267/* mysql_table(5), Postfix MYSQL client
268/* nisplus_table(5), Postfix NIS+ client
269/* pcre_table(5), Associate PCRE pattern with value
270/* pgsql_table(5), Postfix PostgreSQL client
271/* regexp_table(5), Associate POSIX regexp pattern with value
272/* socketmap_table(5), Postfix socketmap client
273/* sqlite_table(5), Postfix SQLite database driver
274/* tcp_table(5), Postfix client-server table lookup
275/*
276/* Daemon processes:
277/* anvil(8), Postfix connection/rate limiting
278/* bounce(8), defer(8), trace(8), Delivery status reports
279/* cleanup(8), canonicalize and enqueue message
280/* discard(8), Postfix discard delivery agent
281/* dnsblog(8), DNS black/whitelist logger
282/* error(8), Postfix error delivery agent
283/* flush(8), Postfix fast ETRN service
284/* local(8), Postfix local delivery agent
285/* master(8), Postfix master daemon
286/* oqmgr(8), old Postfix queue manager
287/* pickup(8), Postfix local mail pickup
288/* pipe(8), deliver mail to non-Postfix command
289/* postscreen(8), Postfix zombie blocker
290/* proxymap(8), Postfix lookup table proxy server
291/* qmgr(8), Postfix queue manager
292/* qmqpd(8), Postfix QMQP server
293/* scache(8), Postfix connection cache manager
294/* showq(8), list Postfix mail queue
295/* smtp(8), lmtp(8), Postfix SMTP+LMTP client
296/* smtpd(8), Postfix SMTP server
297/* spawn(8), run non-Postfix server
298/* tlsmgr(8), Postfix TLS cache and randomness manager
299/* tlsproxy(8), Postfix TLS proxy server
300/* trivial-rewrite(8), Postfix address rewriting
301/* verify(8), Postfix address verification
302/* virtual(8), Postfix virtual delivery agent
303/*
304/* Other:
305/* syslogd(8), system logging
306/* README FILES
307/* .ad
308/* .fi
309/* Use "\fBpostconf readme_directory\fR" or
310/* "\fBpostconf html_directory\fR" to locate this information.
311/* .na
312/* .nf
313/* OVERVIEW, overview of Postfix commands and processes
314/* BASIC_CONFIGURATION_README, Postfix basic configuration
315/* ADDRESS_REWRITING_README, Postfix address rewriting
316/* SMTPD_ACCESS_README, SMTP relay/access control
317/* CONTENT_INSPECTION_README, Postfix content inspection
318/* QSHAPE_README, Postfix queue analysis
319/* LICENSE
320/* .ad
321/* .fi
322/* The Secure Mailer license must be distributed with this software.
323/* AUTHOR(S)
324/* Wietse Venema
325/* IBM T.J. Watson Research
326/* P.O. Box 704
327/* Yorktown Heights, NY 10598, USA
328/*
329/* Wietse Venema
330/* Google, Inc.
331/* 111 8th Avenue
332/* New York, NY 10011, USA
333/*
334/* TLS support by:
335/* Lutz Jaenicke
336/* Brandenburg University of Technology
337/* Cottbus, Germany
338/*
339/* Victor Duchovni
340/* Morgan Stanley
341/*
342/* SASL support originally by:
343/* Till Franke
344/* SuSE Rhein/Main AG
345/* 65760 Eschborn, Germany
346/*
347/* LMTP support originally by:
348/* Philip A. Prindeville
349/* Mirapoint, Inc.
350/* USA.
351/*
352/* Amos Gouaux
353/* University of Texas at Dallas
354/* P.O. Box 830688, MC34
355/* Richardson, TX 75083, USA
356/*
357/* IPv6 support originally by:
358/* Mark Huizer, Eindhoven University, The Netherlands
359/* Jun-ichiro 'itojun' Hagino, KAME project, Japan
360/* The Linux PLD project
361/* Dean Strik, Eindhoven University, The Netherlands
362/*--*/
363
364/* System library. */
365
366#include <sys_defs.h>
367#include <sys/stat.h>
368#include <vstream.h>
369#include <stdlib.h>
370#include <unistd.h>
371#include <string.h>
372#include <fcntl.h>
373#include <syslog.h>
374#ifdef USE_PATHS_H
375#include <paths.h>
376#endif
377
378/* Utility library. */
379
380#include <msg.h>
381#include <msg_vstream.h>
382#include <msg_syslog.h>
383#include <stringops.h>
384#include <clean_env.h>
385#include <argv.h>
386#include <safe.h>
387#include <warn_stat.h>
388
389/* Global library. */
390
391#include <mail_conf.h>
392#include <mail_params.h>
393#include <mail_version.h>
394#include <mail_parm_split.h>
395
396/* Additional installation parameters. */
397
398static char *var_sendmail_path;
399static char *var_mailq_path;
400static char *var_newalias_path;
401static char *var_manpage_dir;
402static char *var_sample_dir;
403static char *var_readme_dir;
404static char *var_html_dir;
405
406/* check_setenv - setenv() with extreme prejudice */
407
408static void check_setenv(char *name, char *value)
409{
410#define CLOBBER 1
411 if (setenv(name, value, CLOBBER) < 0)
412 msg_fatal("setenv: %m");
413}
414
415MAIL_VERSION_STAMP_DECLARE;
416
417/* main - run administrative script from controlled environment */
418
419int main(int argc, char **argv)
420{
421 char *script;
422 struct stat st;
423 char *slash;
424 int fd;
425 int ch;
426 ARGV *import_env;
427 static const CONFIG_STR_TABLE str_table[] = {
428 VAR_SENDMAIL_PATH, DEF_SENDMAIL_PATH, &var_sendmail_path, 1, 0,
429 VAR_MAILQ_PATH, DEF_MAILQ_PATH, &var_mailq_path, 1, 0,
430 VAR_NEWALIAS_PATH, DEF_NEWALIAS_PATH, &var_newalias_path, 1, 0,
431 VAR_MANPAGE_DIR, DEF_MANPAGE_DIR, &var_manpage_dir, 1, 0,
432 VAR_SAMPLE_DIR, DEF_SAMPLE_DIR, &var_sample_dir, 1, 0,
433 VAR_README_DIR, DEF_README_DIR, &var_readme_dir, 1, 0,
434 VAR_HTML_DIR, DEF_HTML_DIR, &var_html_dir, 1, 0,
435 0,
436 };
437 int force_single_instance;
438 ARGV *my_argv;
439
440 /*
441 * Fingerprint executables and core dumps.
442 */
443 MAIL_VERSION_STAMP_ALLOCATE;
444
445 /*
446 * Be consistent with file permissions.
447 */
448 umask(022);
449
450 /*
451 * To minimize confusion, make sure that the standard file descriptors
452 * are open before opening anything else. XXX Work around for 44BSD where
453 * fstat can return EBADF on an open file descriptor.
454 */
455 for (fd = 0; fd < 3; fd++)
456 if (fstat(fd, &st) == -1
457 && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
458 msg_fatal("open /dev/null: %m");
459
460 /*
461 * Set up diagnostics. XXX What if stdin is the system console during
462 * boot time? It seems a bad idea to log startup errors to the console.
463 * This is UNIX, a system that can run without hand holding.
464 */
465 if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
466 argv[0] = slash + 1;
467 if (isatty(STDERR_FILENO))
468 msg_vstream_init(argv[0], VSTREAM_ERR);
469 msg_syslog_init(argv[0], LOG_PID, LOG_FACILITY);
470
471 /*
472 * Check the Postfix library version as soon as we enable logging.
473 */
474 MAIL_VERSION_CHECK;
475
476 /*
477 * The mail system must be run by the superuser so it can revoke
478 * privileges for selected operations. That's right - it takes privileges
479 * to toss privileges.
480 */
481 if (getuid() != 0) {
482 msg_error("to submit mail, use the Postfix sendmail command");
483 msg_fatal("the postfix command is reserved for the superuser");
484 }
485 if (unsafe() != 0)
486 msg_fatal("the postfix command must not run as a set-uid process");
487
488 /*
489 * Parse switches.
490 */
491 while ((ch = GETOPT(argc, argv, "c:Dv")) > 0) {
492 switch (ch) {
493 default:
494 msg_fatal("usage: %s [-c config_dir] [-Dv] command", argv[0]);
495 case 'c':
496 if (*optarg != '/')
497 msg_fatal("-c requires absolute pathname");
498 check_setenv(CONF_ENV_PATH, optarg);
499 break;
500 case 'D':
501 check_setenv(CONF_ENV_DEBUG, "");
502 break;
503 case 'v':
504 msg_verbose++;
505 check_setenv(CONF_ENV_VERB, "");
506 break;
507 }
508 }
509 force_single_instance = (getenv(CONF_ENV_PATH) != 0);
510
511 /*
512 * Copy a bunch of configuration parameters into the environment for easy
513 * access by the maintenance shell script.
514 */
515 mail_conf_read();
516 get_mail_conf_str_table(str_table);
517
518 /*
519 * Alert the sysadmin that the backwards-compatible settings are still in
520 * effect.
521 */
522 if (var_compat_level < CUR_COMPAT_LEVEL) {
523 msg_info("Postfix is running with backwards-compatible default "
524 "settings");
525 msg_info("See http://www.postfix.org/COMPATIBILITY_README.html "
526 "for details");
527 msg_info("To disable backwards compatibility use \"postconf "
528 VAR_COMPAT_LEVEL "=%d\" and \"postfix reload\"",
529 CUR_COMPAT_LEVEL);
530 }
531
532 /*
533 * Environment import filter, to enforce consistent behavior whether this
534 * command is started by hand, or at system boot time. This is necessary
535 * because some shell scripts use environment settings to override
536 * main.cf settings.
537 */
538 import_env = mail_parm_split(VAR_IMPORT_ENVIRON, var_import_environ);
539 clean_env(import_env->argv);
540 argv_free(import_env);
541
542 check_setenv("PATH", ROOT_PATH); /* sys_defs.h */
543 check_setenv(CONF_ENV_PATH, var_config_dir);/* mail_conf.h */
544
545 check_setenv(VAR_COMMAND_DIR, var_command_dir); /* main.cf */
546 check_setenv(VAR_DAEMON_DIR, var_daemon_dir); /* main.cf */
547 check_setenv(VAR_DATA_DIR, var_data_dir); /* main.cf */
548 check_setenv(VAR_META_DIR, var_meta_dir); /* main.cf */
549 check_setenv(VAR_QUEUE_DIR, var_queue_dir); /* main.cf */
550 check_setenv(VAR_CONFIG_DIR, var_config_dir); /* main.cf */
551 check_setenv(VAR_SHLIB_DIR, var_shlib_dir); /* main.cf */
552
553 /*
554 * Do we want to keep adding things here as shell scripts evolve?
555 */
556 check_setenv(VAR_MAIL_OWNER, var_mail_owner); /* main.cf */
557 check_setenv(VAR_SGID_GROUP, var_sgid_group); /* main.cf */
558 check_setenv(VAR_SENDMAIL_PATH, var_sendmail_path); /* main.cf */
559 check_setenv(VAR_MAILQ_PATH, var_mailq_path); /* main.cf */
560 check_setenv(VAR_NEWALIAS_PATH, var_newalias_path); /* main.cf */
561 check_setenv(VAR_MANPAGE_DIR, var_manpage_dir); /* main.cf */
562 check_setenv(VAR_SAMPLE_DIR, var_sample_dir); /* main.cf */
563 check_setenv(VAR_README_DIR, var_readme_dir); /* main.cf */
564 check_setenv(VAR_HTML_DIR, var_html_dir); /* main.cf */
565
566 /*
567 * Make sure these directories exist. Run the maintenance scripts with as
568 * current directory the mail database.
569 */
570 if (chdir(var_command_dir))
571 msg_fatal("chdir(%s): %m", var_command_dir);
572 if (chdir(var_daemon_dir))
573 msg_fatal("chdir(%s): %m", var_daemon_dir);
574 if (chdir(var_queue_dir))
575 msg_fatal("chdir(%s): %m", var_queue_dir);
576
577 /*
578 * Run the management script.
579 */
580 if (force_single_instance
581 || argv_split(var_multi_conf_dirs, CHARS_COMMA_SP)->argc == 0) {
582 script = concatenate(var_daemon_dir, "/postfix-script", (char *) 0);
583 if (optind < 1)
584 msg_panic("bad optind value");
585 argv[optind - 1] = script;
586 execvp(script, argv + optind - 1);
587 msg_fatal("%s: %m", script);
588 }
589
590 /*
591 * Hand off control to a multi-instance manager.
592 */
593 else {
594 if (*var_multi_wrapper == 0)
595 msg_fatal("multi-instance support is requested, but %s is empty",
596 VAR_MULTI_WRAPPER);
597 my_argv = argv_split(var_multi_wrapper, CHARS_SPACE);
598 do {
599 argv_add(my_argv, argv[optind], (char *) 0);
600 } while (argv[optind++] != 0);
601 execvp(my_argv->argv[0], my_argv->argv);
602 msg_fatal("%s: %m", my_argv->argv[0]);
603 }
604}
605